package org.jetlinks.pro.logging.controller;

import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.reactor.excel.ReactorExcel;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryNoPagingOperation;
import org.hswebframework.web.api.crud.entity.QueryOperation;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.authorization.annotation.QueryAction;
import org.hswebframework.web.authorization.annotation.Resource;
import org.jetlinks.pro.logging.excel.SystemLoggerExcelInfo;
import org.jetlinks.pro.logging.service.SystemLoggerService;
import org.jetlinks.pro.logging.system.SerializableSystemLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * @author bsetfeng
 * @since 1.0
 **/
@RestController
@RequestMapping("/logger/system")
@Resource(id = "system-logger", name = "系统日志")
@Tag(name = "日志管理")
@Slf4j
public class SystemLoggerController {

    @Autowired
    private SystemLoggerService loggerService;

    private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory();

    @GetMapping("/_query")
    @QueryAction
    @QueryOperation(summary = "查询系统日志")
    public Mono<PagerResult<SerializableSystemLog>> getSystemLogger(@Parameter(hidden = true) QueryParamEntity queryParam) {
        return loggerService.getSystemLogger(queryParam);
    }


    @GetMapping("/download.{format}/_query")
    @QueryAction
    @QueryNoPagingOperation(summary = "导出全部系统日志")
    public Mono<Void> downloadSystemLogger(ServerHttpResponse response,
                                           @Parameter(hidden = true) QueryParamEntity queryParam,
                                           @PathVariable @Parameter(description = "文件格式,支持csv,xlsx") String format) throws IOException {

        response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION,
                                  "attachment; filename=".concat(URLEncoder.encode("系统日志." + format, StandardCharsets.UTF_8
                                      .displayName())));
        return Mono.just(SystemLoggerExcelInfo.getLoggerHeaderMapping())
                   .flatMapMany(headers -> ReactorExcel
                       .<SystemLoggerExcelInfo>writer(format)
                       .headers(headers)
                       .converter(systemLoggerExcelInfo -> systemLoggerExcelInfo.toMap(format))
                       .writeBuffer(SystemLoggerExcelInfo.getLoggerContentMapping(loggerService.getAllSystemLogger(queryParam.noPaging())), 512 * 1024))
                   .doOnError(err -> log.error(err.getMessage(), err))
                   .map(bufferFactory::wrap)
                   .as(response::writeWith)
            ;

    }


}